package com.lvmama.dashboard.core.rop;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
import org.springframework.util.ReflectionUtils.MethodFilter;

import com.lvmama.dashboard.core.annotation.AjaxMethod;

public class AjaxServiceHandler implements ApplicationContextAware, InitializingBean {

	private static final Log log = LogFactory.getLog(AjaxServiceHandler.class);

	private ApplicationContext applicationContext;

	private static Map<String, AjaxMethodHandler> methodHandlerPool;

	public AjaxServiceHandler() {
		methodHandlerPool = new HashMap<String, AjaxMethodHandler>();
	}

	public void addHandlerMathod(String method, AjaxMethodHandler handler) {
		AjaxMethodHandler targetHandler = methodHandlerPool.get(method);
		if (targetHandler != null) {
			log.error("重复Ajax定义，Method:" + method);
			throw new RuntimeException();
		}
		methodHandlerPool.put(method, handler);
	}

	public AjaxMethodHandler getHandler(String method) {
		AjaxMethodHandler targetHandler = methodHandlerPool.get(method);
		if (targetHandler == null) {
			throw new RuntimeException(MessageFormat.format("{0} 对应方法未找到", method));
		}
		return targetHandler;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		try {
			String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class);
			for (final String beanName : beanNames) {
				Class<?> handlerType = this.applicationContext.getType(beanName);
				ReflectionUtils.doWithMethods(handlerType, new MethodCallback() {
					@Override
					public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
						AjaxMethod ajaxMethod = method.getAnnotation(AjaxMethod.class);
						AjaxMethodHandler serviceMethodHandler = new AjaxMethodHandler();
						serviceMethodHandler.setHandler(applicationContext.getBean(beanName));
						serviceMethodHandler.setHandlerMethod(method);
						log.info("初始化Ajax方法：" + ajaxMethod.ajaxmethod());
						addHandlerMathod(ajaxMethod.ajaxmethod(), serviceMethodHandler);
					}
				}, new MethodFilter() {
					@Override
					public boolean matches(Method method) {
						return AnnotationUtils.findAnnotation(method, AjaxMethod.class) != null;
					}
				});
			}
			log.info("共 初始化 " + methodHandlerPool.size() + " 个Ajax方法");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
